#pragma once
#include "cnfparser.hpp"
#include "sudoku.hpp"
#include "solver.hpp"

void menu(int choice);
int display(void);
void instructionsSAT(void);
void instructionsSudoku(void);
Status isOK(int arr[][10], int posX, int posY, int value);
Status isEqual(int arr[][10]);
void str_replace(char *str1, char *str2, char *str3);
/***********************
 * param: int(根据标记来判断选择哪种菜单)
 * return: void
 * res: 根据标记来判断选择哪种菜单
***********************/
void menu(int choice)
{
    switch (choice)
    {
    case 0:
    {
        printf("-------------------------------------------\n");
        printf("|                    MENU                 |\n");
        printf("|            Sudoku(1) or SAT(2)          |\n");
        printf("|                  Exit(0)                |\n");
        printf("-------------------------------------------\n");
        break;
    }
    case 1:
    {
        printf("--------------------------------------------\n");
        printf("|             welcome to Sudoku            |\n");
        printf("|              1. instructions             |\n");
        printf("|              2. begin game               |\n");
        printf("|              3. answer                   |\n");
        printf("|              4. solve other cnf          |\n");
        printf("|              5. solve other sudoku       |\n");
        printf("|              0. return                   |\n");
        printf("--------------------------------------------\n");
        break;
    }
    case 2:
    {
        printf("-------------------------------------------\n");
        printf("|              welcome to SAT             |\n");
        printf("|              1. instructions            |\n");
        printf("|              2. test                    |\n");
        printf("|              0. return                  |\n");
        printf("-------------------------------------------\n");
        break;
    }
    default:
        break;
    }
}

int display(void)
{
    int choice = 0, branch = 0;
    while (true)
    {
        system("cls");
        menu(0);
        printf("[input]: ");
        scanf("%d", &choice);
        if (choice == 0)
        {
            printf("Exit success!\n");
            return 0;
        }
        else if (choice == 1)
        {
            while (true)
            {
                system("cls");
                menu(1);
                printf("[input]: ");
                scanf("%d", &branch);
                if (branch == 0)
                {
                    break;
                }
                switch (branch)
                {
                case 1:
                {
                    instructionsSudoku();
                    system("pause");
                    break;
                }
                case 2:
                {
                    char sudokuName[30];
                    printf("Please input the sudoku name: ");
                    scanf("%s", sudokuName);
                    strcat(sudokuName, ".cnf");
                    CreateFullShudu();
                    DigShudu(zcxShudu);
                    CreateShuduCNF(zcxShudu, sudokuName);
                    printf("return with 0 0 0\ncommit with 0 0 1");
                    int posX, posY, value;
                    while (true)
                    {
                        system("cls");
                        printShudu(zcxShudu);
                        printf("Please input (posX,posY,value): ");
                        scanf("%d %d %d", &posX, &posY, &value);
                        if (posX == 0 && posY == 0)
                        {
                            if (value == 0)
                                break;
                            else if (value == 1)
                            {
                                // 判断答案
                                if (isEqual(zcxShudu))
                                    printf("You are right!");
                                else
                                    printf("You are error!");
                                break;
                            }
                        }
                        if (!isOK(zcxShudu, posX, posY, value))
                        {
                            printf("Input error! please input again");
                            system("pause");
                        }
                    }
                }
                case 3:
                {
                    printShudu(_shudu);
                    system("pause");
                    break;
                }
                case 4:
                {
                    char filename[30];
                    int arr[10][10];
                    clock_t begin, end;
                    printf("Please input the filename of sudoku: ");
                    scanf("%s", filename);
                    LinkClause C = InitClauseTable(filename);
                    begin = clock();
                    DPLL(C, 3);
                    end = clock();
                    str_replace(filename, ".cnf", ".res");
                    saveRes(filename, end - begin);
                    GetShuduValue(arr);
                    printShudu(arr);
                    system("pause");
                    break;
                }
                case 5:
                {
                    int otherSudoku[10][10];
                    char str[100], sudokuName[30], f1[30], f2[30];
                    int cnt = 0, res;
                    clock_t begin, end;
                    printf("Please input the sudoku name: ");
                    scanf("%s", sudokuName);
                    strcpy(f1, sudokuName);
                    strcpy(f2, sudokuName);
                    strcat(f1, ".cnf");
                    strcat(f2, ".res");
                    printf("Please input puzzle: ");
                    scanf("%s", str);
                    for (int i = 1; i <= 9; i++)
                        for (int j = 1; j <= 9; j++)
                        {
                            if (str[cnt] == '.')
                                otherSudoku[i][j] = 0;
                            else
                                otherSudoku[i][j] = str[cnt] - '0';
                            cnt++;
                        }
                    printShudu(otherSudoku);
                    CreateShuduCNF(otherSudoku, f1);
                    LinkClause C = InitClauseTable(f1);
                    begin = clock();
                    res = DPLL(C, 3);
                    end = clock();
                    if (res)
                    {
                        printf("The result is: \n");
                        saveRes(f2, end - begin);
                        GetShuduValue(otherSudoku);
                        printShudu(otherSudoku);
                    }
                    else
                    {
                        printf("The sudoku can't be solved\n");
                    }
                    system("pause");
                    break;
                }
                default:
                    break;
                }
            }
        }
        else if (choice == 2)
        {
            while (true)
            {
                system("cls");
                menu(2);
                printf("[input]: ");
                scanf("%d", &branch);
                if (branch == 0)
                {
                    break;
                }
                switch (branch)
                {
                case 1:
                {
                    instructionsSAT();
                    system("pause");
                    break;
                }
                case 2:
                {
                    char filename[30];
                    int idea = 3, res;
                    clock_t begin, end;
                    printf("Please input the filename of cnf: ");
                    scanf("%s", filename);
                    LinkClause C = InitClauseTable(filename);
                    printf("read File: \n");
                    TraverseClauseTable(C);
                    printf("please input the idea of find v: ");
                    scanf("%d", &idea);
                    begin = clock();
                    res = DPLL(C, idea);
                    end = clock();
                    if (res == TRUE)
                    {
                        str_replace(filename, ".cnf", ".res");
                        saveRes(filename, end - begin);
                        myPrint();
                        printf("True and use %d ms\n", end - begin);
                    }
                    else
                    {
                        printf("unsat! use %d ms\n", end - begin);
                    }
                    system("pause");
                    break;
                }
                default:
                    break;
                }
            }
        }
        else
        {
            printf("Input error! please input again: ");
        }
    }
    return 0;
}

void instructionsSudoku(void)
{
    printf("Empty now\n");
}

void instructionsSAT(void)
{
    printf("Empty now\n");
}

Status isOK(int arr[][10], int posX, int posY, int value)
{
    if ((posX >= 1 && posX <= 9) &&
        (posY >= 1 && posY <= 9) &&
        (value >= 1 && value <= 9) &&
        (arr[posX][posY] == 0))
    {
        arr[posX][posY] = value;
        return OK;
    }
    return FALSE;
}

Status isEqual(int arr[][10])
{
    for (int i = 1; i <= 9; i++)
        for (int j = 1; j <= 9; j++)
            if (arr[i][j] != _shudu[i][j])
                return FALSE;
    return TRUE;
}

void str_replace(char *str1, char *str2, char *str3)
{
    int i, j, k, done, count = 0, gap = 0;
    char temp[300];
    for (i = 0; i < strlen(str1); i += gap)
    {
        if (str1[i] == str2[0])
        {
            done = 0;
            for (j = i, k = 0; k < strlen(str2); j++, k++)
            {
                if (str1[j] != str2[k])
                {
                    done = 1;
                    gap = k;
                    break;
                }
            }
            if (done == 0)
            { // 已找到待替换字符串并替换
                for (j = i + strlen(str2), k = 0; j < strlen(str1); j++, k++)
                { // 保存原字符串中剩余的字符
                    temp[k] = str1[j];
                }
                temp[k] = '\0'; // 将字符数组变成字符串
                for (j = i, k = 0; k < strlen(str3); j++, k++)
                { // 字符串替换
                    str1[j] = str3[k];
                    count++;
                }
                for (k = 0; k < strlen(temp); j++, k++)
                { // 剩余字符串回接
                    str1[j] = temp[k];
                }
                str1[j] = '\0'; // 将字符数组变成字符串
                gap = strlen(str2);
            }
        }
        else
        {
            gap = 1;
        }
    }
    if (count == 0)
    {
        printf("Can't find the replaced string!\n");
    }
    return;
}